home *** CD-ROM | disk | FTP | other *** search
/ Maclife 42 / MACLIFE42.ISO.7z / MACLIFE42.ISO / FreeWare200 / 圧縮伸張⁄コード / MacGzip / MacGzip 1.1.2 Source.sea / MacGzip 1.1.2 Source / Mac / EventLoop.c next >
Text File  |  1997-04-01  |  19KB  |  947 lines

  1. /*
  2.  * Copyright (C) 1995  SPDsoft
  3.  * 
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdarg.h>
  8. #include <limits.h>
  9.  
  10. /*
  11.  * THINK_C 8.0 extra includes (Not in MacHeaders)
  12.  */
  13. #include <Aliases.h>
  14. #include <Sound.h>
  15.  
  16.  
  17. #include "MacGzip.h"
  18. #include "GzErrors.h"
  19. #include "ErrorStrings.h"
  20. #include "GzPStrings.h"
  21.  
  22. #include "Prefs.h"
  23. #include "FileTypes.h"
  24. #include "Globals.h"
  25. #include "Work.h"
  26.  
  27. #define        CGF_MAX_TYPES        4
  28.  
  29. #define        CustomGetFileDLOG    160
  30. #define        kShowAnyButton        10
  31.  
  32. #if GENERATINGCFM || USESROUTINEDESCRIPTORS
  33. #  define CreateRoutineDescriptor(info, proc)                                    ¥
  34.         RoutineDescriptor g##proc##RD = BUILD_ROUTINE_DESCRIPTOR(info, proc)
  35. #  define GetRoutineAddress(proc)    (&g##proc##RD)
  36. #else
  37. #  define GetRoutineAddress(proc)    proc
  38. #endif
  39.  
  40. /************************************************************************************
  41.  * 
  42.  * Movable Modal Stuff
  43.  *
  44.  *        MM from C.K. Haun (Apple DTS) (MModal 7.0)
  45.  *        Color Alysoft Solutions <heathcot@bnr.ca> (CModalProgress)
  46.  */
  47.  
  48. /*
  49.  * Prototypes
  50.  */
  51.  
  52. static void        DrawMovable(WindowPtr myWindow);
  53. static void        DrawBar(short part);
  54. static short    FixMMString( void );
  55. static void        DrawMsg(void);
  56. static void        BeginOfTask( void );
  57. static Boolean    EndOfTask( int errorcode );
  58. static int        RecurseDir(long dirIDToSearch);
  59. static int        DoOpen( FSSpec *fs );
  60. /*
  61.  * (Too many) Globals (we could group them in a struct and set it in refCon)
  62.  */
  63. #if GENERATINGCFM && !defined(__MWERKS__)
  64.     QDGlobals    qd;
  65. #endif
  66.  
  67. static Boolean            gTask = FALSE; 
  68. Boolean                    UseMModalProg=false;
  69.  
  70. static Rect                barRect; 
  71. static Rect                greyRect;
  72. static Rect                r;            /* Window's rect */
  73. static Rect                MsgRect;
  74.  
  75. static ControlHandle    ButtonHndl = nil;
  76.  
  77. long int                SPDEnd,
  78.                         *SPDNow = nil;
  79.  
  80. Str255                    SPDPstr="¥p";
  81. char*                    SPDpstr=(char*)SPDPstr;
  82.  
  83. static    Boolean            gDirtyStr;
  84.  
  85. #define    kMyModalKind    1000
  86. #define    kMyModalID        150
  87. #define    kCancelButton    150
  88.  
  89. #define    kIndicatorOutline    0x0001
  90. #define    kIndicatorContent    0x0002
  91.  
  92. #define    BarHeight        13
  93. #define    BarMargin        20
  94.  
  95. /************************************************************************************
  96.  * 
  97.  * more generic globals
  98.  */
  99.  
  100. typedef struct
  101. {
  102.     short    numTypes;
  103.     OSType    typeList[CGF_MAX_TYPES];
  104.     Boolean    ShowAny;
  105.     Boolean    Inited;
  106. }    TypeList;
  107.  
  108.  
  109. extern TSufMap                gSufMap;
  110.  
  111.  
  112. static pascal short        MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr );
  113. static pascal Boolean    MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr);
  114.  
  115.  
  116. extern void        about(void);
  117. extern Boolean    DoPrefsDialog(PrefsTypePtr thePrefs, AliasHandle * theFldrAlias);
  118. Boolean            EventLoop( void );
  119. static Boolean    DoCommand( long mResult );
  120. static Boolean    DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent);
  121.  
  122.  
  123. extern int gzip ( FSSpec *fs );
  124.  
  125. /************************************************************************************
  126.  * 
  127.  *  main event loop. Returns true when it has to end
  128.  */
  129.  
  130. Boolean EventLoop( void )
  131. {
  132.     typedef long (*MyProcPtr)( WindowPtr w );
  133.     
  134.     EventRecord                    theEvent;
  135.     MyProcPtr                    drawProc;
  136.     WindowPtr                    twindow;
  137.     short                        windowPart;
  138.     static long int                TheLastTime;
  139.     
  140.     Boolean                        done = FALSE;
  141.     static long                    SPDLast = 0;
  142.  
  143.  
  144.     if (gApp.quit)
  145.         return true;
  146.         
  147.     if (gApp.Working)
  148.     {
  149.         UpdateAnimatedCursor( gApp.Cursor, TickCount() );
  150.         /*
  151.          * Update bar
  152.          */
  153.          
  154.         if ((UseMModalProg) && ( SPDLast != *SPDNow ))
  155.         {
  156.             greyRect.left = greyRect.right;
  157.             
  158.             greyRect.right = 
  159.                 ((float)*SPDNow/SPDEnd)*(barRect.right-barRect.left) + barRect.left;
  160.  
  161.             DrawBar(kIndicatorContent);
  162.             SPDLast = *SPDNow;
  163.         }
  164.     
  165.         /*
  166.          * Update string
  167.          */
  168.         if ((gDirtyStr) && (UseMModalProg))
  169.             DrawMsg();
  170.     }
  171.     else if ( !gTask )
  172.     {
  173.         if ( !empty_work )
  174.         {
  175.             FSSpec        fs;
  176.             int            rescode=0;
  177.             
  178.             BeginOfTask();
  179.  
  180.             do
  181.             {
  182.                 if ( noErr == get_work(    &gApp.KeysMode, &gApp.Op, &gApp.Prompt, &fs )) 
  183.                 {
  184.                     rescode = DoOpen( &fs );
  185.                     EndOfTask( rescode );
  186.                 }
  187.                 else
  188.                     break;
  189.                     
  190.             } while (!gApp.quit && !empty_work);
  191.             
  192.             done = (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone ));
  193.         }
  194.     }
  195.         
  196.     while((GetNextEvent(everyEvent, &theEvent)) && !done)
  197.     {
  198.         switch( theEvent.what )
  199.         {
  200.             case keyDown:
  201.             case autoKey: 
  202.                 {
  203.                     register char theChar;
  204.     
  205.                     theChar = theEvent.message & charCodeMask;
  206.                     
  207.                     if ((theEvent.modifiers & cmdKey) != 0)
  208.                     {
  209.                         if ((theChar == '.' ) && gApp.Working)
  210.                         {
  211.                             SetCursor(&qd.arrow);
  212.                             done = true;
  213.                         }
  214.                         else
  215.                             done = DoCommand( MenuKey(theChar) );
  216.                     }
  217.                                     
  218.                     break;
  219.                 }
  220.                 
  221.             case mouseDown:
  222.             
  223.                 windowPart = FindWindow(theEvent.where, &twindow);
  224.                 
  225.                 done = DoMouseDown(windowPart, twindow, &theEvent);
  226.                 
  227.                 break;
  228.                 
  229.                 
  230.             case activateEvt:
  231.             case updateEvt:
  232.             
  233.                 if ( gApp.Working ) /* if working */
  234.                 {
  235.                     /*
  236.                      * Make sure it's my window before I jump through the refCon
  237.                      * Why, since DA's have they're own layer in 7.0?
  238.                      * BECAUSE there are other people in the universe who will
  239.                      * add things to your windowList.BalloonWriter, for example,
  240.                      * so you still need to be careful
  241.                      */
  242.                      
  243.                     if (((WindowPeek)theEvent.message)->windowKind == kMyModalKind)
  244.                     {
  245.                         drawProc = (MyProcPtr)GetWRefCon((WindowPtr)theEvent.message);
  246.                         drawProc((WindowPtr)theEvent.message);
  247.                     }
  248.                 }
  249.  
  250.                 break;
  251.                 
  252.             case diskEvt:
  253.             
  254.                 if ((theEvent.message >> 16) != noErr)
  255.                 {
  256.                     Point myPoint={100,100};
  257.                 
  258.                     err = DIBadMount(myPoint, theEvent.message);
  259.                     
  260.                     DoError(SYS_ERR,WARN_ERR,GetErrFmt(GENERIC, BAD_DISK));
  261.                 }
  262.                 
  263.                 break;
  264.  
  265.             case osEvt:
  266.                 switch ((theEvent.message >> 24) & 0x0ff)
  267.                 {
  268.                     case suspendResumeMessage:
  269.                         
  270.                         
  271.                     
  272.                         if ((theEvent.message & resumeFlag) == 0) // suspend 
  273.                         {
  274.                             gApp.InForeground = FALSE;
  275.                             SetCursor(&qd.arrow);
  276.                         }
  277.                         else
  278.                         {                                        // resume
  279.                             gApp.InForeground = TRUE;
  280.                             if (gApp.Working)
  281.                                 UpdateAnimatedCursor( gApp.Cursor, theEvent.when );
  282.                             else
  283.                                 SetCursor(&qd.arrow);
  284.                         }
  285.                         break;
  286.                         
  287.                     case mouseMovedMessage:
  288.                         break;
  289.                 }
  290.                 break;
  291.                 
  292.             case kHighLevelEvent:
  293.             
  294.                 AEProcessAppleEvent (&theEvent);
  295.                 done = gApp.quit;
  296.                 break;
  297.  
  298.             default:
  299.                 break;
  300.  
  301.         }
  302.     }
  303.     
  304.     return done;
  305. }
  306.  
  307. static Boolean DoCommand( long mResult )
  308. {
  309.     short    theItem;
  310.     Str255    name;
  311.     Boolean done=FALSE;
  312.  
  313. /* custom get file stuff */
  314.  
  315.     StandardFileReply    mySFR;
  316.  
  317. #if GENERATINGCFM || USESROUTINEDESCRIPTORS
  318.     CreateRoutineDescriptor(uppFileFilterYDProcInfo, MyCustomFileFilter);
  319.     CreateRoutineDescriptor(uppDlgHookYDProcInfo, MySFGetDlgHook);
  320. #endif
  321.             
  322.             
  323.     static TypeList        MyTypeList = {
  324.                                         4,
  325.                                         { 'Gzip','ZIVU','ZIVM','pZIP' },
  326.                                         FALSE,
  327.                                         FALSE
  328.                                     };
  329.     Point                sfgfpos = { -1, -1 };
  330.     
  331.  
  332.     theItem = LoWord(mResult);
  333.     
  334.     switch( HiWord(mResult) )
  335.     {
  336.         case kAppleMenu:
  337.             if( theItem > 2 )
  338.             {
  339.                 GrafPtr savePort;
  340.                 GetMenuItemText(GetMenuHandle(kAppleMenu), theItem, name);
  341.                 GetPort(&savePort);
  342.                     OpenDeskAcc(name);
  343.                 SetPort(savePort);
  344.             }
  345.             else
  346.             {
  347.                 about();
  348.             }
  349.             break;
  350.  
  351.         case kFileMenu:
  352.         
  353.             switch( theItem )
  354.             {
  355.                 case kfmExpand:
  356.                 case kfmOpen:
  357.  
  358.  
  359.                     CustomGetFile(
  360.                                 (FileFilterYDUPP)GetRoutineAddress(MyCustomFileFilter),
  361.                                 -1, *(SFTypeList *)&MyTypeList.typeList,
  362.                                 &mySFR,
  363.                                 CustomGetFileDLOG,
  364.                                 sfgfpos,
  365.                                 (DlgHookYDUPP)GetRoutineAddress(MySFGetDlgHook),
  366.                                 nil,
  367.                                 nil,
  368.                                 nil,
  369.                                 (void *) &MyTypeList
  370.                             );
  371.  
  372.                     if( mySFR.sfGood )
  373.                     {
  374.                         
  375.                         /* do something */
  376.                         BeginOfTask();
  377.                         
  378.                         gApp.KeysMode =        0;
  379.                         gApp.KeysOp =        0;
  380.                         gApp.Op = ( theItem == kfmExpand ? kMisc_gunzip : kMisc_auto );
  381.                         gApp.Prompt =     ( theItem == kfmExpand );        
  382.                         
  383.                         gSufMap.Type = mySFR.sfType;
  384.                         
  385.                         done = EndOfTask( gzip( &mySFR.sfFile)  );
  386.                     }
  387.                 
  388.                     break;
  389.         
  390.                 case kfmCompress:
  391.                 
  392.                     StandardGetFile( nil, -1, nil, &mySFR);
  393.                     if( mySFR.sfGood )
  394.                     {
  395.                         /* do something */
  396.                         
  397.                         BeginOfTask();
  398.                         
  399.                         gApp.KeysMode =        0;
  400.                         gApp.KeysOp =        0;
  401.                         gApp.Op =             kMisc_gzip;
  402.                         gApp.Prompt =         TRUE;        
  403.                         
  404.                         gSufMap.Type = mySFR.sfType;
  405.                         
  406.                         done = EndOfTask( gzip( &mySFR.sfFile)  );
  407.                     }
  408.  
  409.                     break;
  410.  
  411.                 case kfmQuit:
  412.                 
  413.                     gApp.quit = TRUE;
  414.                     done = TRUE;
  415.                     break;
  416.         
  417.                 default:
  418.                 
  419.                     break;
  420.         
  421.             }
  422.             break;
  423.  
  424.         case kEditMenu:
  425.         
  426.             switch( theItem )
  427.             {
  428.                 case kemPrefs:
  429.                 
  430.                     gApp.PrefsChanged = DoPrefsDialog(&gPrefs, &gApp.DFolder);
  431.                     
  432.                     if ( ( gPrefs.Compress.IC || gPrefs.Decompress.IC ) && (gSufMap.ICmappings == nil ))
  433.                         if ( InitICMappings( &(gSufMap.ICinst), &(gSufMap.ICmappings) ) )
  434.                         {
  435.                             /* couldn't init it */
  436.                             gPrefs.Compress.IC = gPrefs.Decompress.IC = FALSE;
  437.                             DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_IC));
  438.                         }
  439.         
  440.                     if (( gPrefs.Decompress.Fetch )&&(gSufMap.FPrefs==nil))
  441.                         if ( InitFetchMappings( &(gSufMap.FPrefsSize), &(gSufMap.FPrefs) ) )
  442.                         {
  443.                             /* couldn't init it */
  444.                             gPrefs.Decompress.Fetch = FALSE;
  445.                             DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_FETCH));
  446.                         }
  447.  
  448.                     break;
  449.                 
  450.                 default:
  451.                 
  452.                     SystemEdit(theItem-1);
  453.                     break;
  454.             }
  455.             break;
  456.             
  457.         default:
  458.             break;
  459.             
  460.     }
  461.  
  462.     HiliteMenu(0);
  463.     return done;
  464. }
  465.  
  466. static Boolean DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent)
  467. {
  468.     Boolean         done=FALSE;
  469.     ControlHandle    WhichCtl;
  470.     
  471.     switch( windowPart )
  472.     {
  473.         case inMenuBar:
  474.             done = DoCommand( MenuSelect(theEvent->where) );
  475.             break;
  476.  
  477.         case inSysWindow:
  478.         
  479.             SystemClick(theEvent, whichWindow);
  480.             break;
  481.  
  482.         case inDrag:
  483.     
  484.             if ( whichWindow != FrontWindow() )
  485.             {
  486.                 /* don't do anything, can't drag a back window */
  487.                 SysBeep(1);
  488.             }
  489.             else
  490.             {
  491.                 DragWindow(whichWindow, theEvent->where, &qd.screenBits.bounds);
  492.                 gApp.PrefsChanged = TRUE;
  493.             }
  494.             break;
  495.                         
  496.         case inContent:
  497.                             
  498.             GlobalToLocal(&theEvent->where);
  499. #ifndef THINK_C                               
  500.             if(kControlButtonPart == FindControl(theEvent->where, whichWindow, &WhichCtl))
  501. #else
  502.             if(inButton == FindControl(theEvent->where, whichWindow, &WhichCtl))
  503. #endif
  504.             {
  505.                 if(0!=TrackControl(WhichCtl, theEvent->where, nil))
  506.                 {
  507.                     SetCursor(&qd.arrow);
  508.                     done = TRUE;
  509.                 }
  510.             }            
  511.             break;
  512.  
  513.         case inGrow:
  514.         case inGoAway:
  515.             /* no such items in MacGzip */
  516.             break;
  517.  
  518.         default:
  519.             break;
  520.     }
  521.     
  522.     return done;
  523. }
  524.  
  525. /*
  526.  * CustomGetFile
  527.  */
  528.  
  529.  
  530. static pascal Boolean MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr)
  531. {
  532.     Boolean result ;
  533.     register short i;
  534.  
  535.     if (
  536.         ( ((TypeList *) myDataPtr)->ShowAny ) ||
  537.         (((pb->fileParam.ioFlAttrib>>4) & 0x01) == 1)    /* is folder */
  538.         )
  539.     {
  540.         result = FALSE;
  541.     }
  542.     else
  543.     {
  544.         for(i=0, result = FALSE; i<    ((TypeList *) myDataPtr)->numTypes ; i++)
  545.         {
  546.             if ( result = (
  547.                             ((TypeList *) myDataPtr)->typeList[i] ==  
  548.                             pb->fileParam.ioFlFndrInfo.fdType
  549.                         ))
  550.             break;        
  551.                             
  552.         }
  553.         result = !result;
  554.     }
  555.     
  556.     
  557.     return result;
  558. }
  559.  
  560. static pascal short  MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr )
  561. {
  562.     short    result = MySFitem;
  563.     short    value;
  564.     short    iType;
  565.     Handle    iHandle;
  566.     Rect    iRect;
  567.     
  568.     switch(MySFitem)
  569.     {
  570.         case sfHookFirstCall:
  571.  
  572.                         GetDialogItem(    dlgPtr, kShowAnyButton,
  573.                                     &iType, &iHandle, &iRect);
  574.  
  575.                         if ( ((TypeList *) myDataPtr)->Inited )
  576.                             SetControlValue( (ControlHandle) iHandle,
  577.                                         (short) ((TypeList *) myDataPtr)->ShowAny );
  578.                         else
  579.                         {
  580.                             ((TypeList *) myDataPtr)->ShowAny = 
  581.                                 (Boolean) GetControlValue( (ControlHandle) iHandle );
  582.                             
  583.                             ((TypeList *) myDataPtr)->Inited = TRUE;
  584.                         }
  585.                         
  586.                         break;
  587.                         
  588.         case kShowAnyButton:
  589.                         
  590.                         GetDialogItem(    dlgPtr, kShowAnyButton,
  591.                                     &iType, &iHandle, &iRect);
  592.                                     
  593.                         value = !GetControlValue( (ControlHandle) iHandle );
  594.                         SetControlValue( (ControlHandle) iHandle , value );
  595.                         
  596.                         ((TypeList *) myDataPtr)->ShowAny = (Boolean) value;
  597.                             
  598.                         result = sfHookRebuildList;        
  599.                         break;
  600.                         
  601.         default:    
  602.     
  603.                         break;
  604.     }
  605.  
  606.     return(result);
  607. }
  608.  
  609. /************************************************************************************
  610.  * 
  611.  * Movable Modal Stuff
  612.  */
  613.  
  614. void InitMovableModal(long int theEnd, long *now )
  615. {
  616.     WindowPtr    myWindow;
  617.  
  618.  
  619.     if (UseMModalProg)
  620.     {
  621.         /* There is already a window on the screen */
  622.         SPDNow=now;
  623.         SPDEnd=(theEnd==0?1:theEnd);
  624.         greyRect.right =    greyRect.left;
  625.         InvalRect(&r);
  626.     }
  627.     else
  628.     {
  629.         if ( gApp.hasColorQD )
  630.             myWindow = GetNewCWindow(kMyModalID, nil, (WindowPtr)-1);
  631.         else
  632.             myWindow = GetNewWindow(kMyModalID, nil, (WindowPtr)-1);
  633.             
  634.         SetWRefCon(myWindow, (long)DrawMovable);
  635.         ((WindowPeek)myWindow)->windowKind = kMyModalKind;
  636.             
  637.         /* move it to the saved position */
  638.         /* move it to 0,0 to avoid any math at all */
  639.         MoveWindow(myWindow, 0, 0, false);
  640.         MoveWindow(myWindow, gPrefs.SavedPoint.h, gPrefs.SavedPoint.v, false);
  641.         
  642.         r = myWindow->portRect;
  643.         
  644.         SPDNow=now;
  645.         SPDEnd=(theEnd==0?1:theEnd);
  646.     
  647.         UseMModalProg=true;
  648.         
  649.             
  650.         barRect.left =        r.left        + BarMargin;
  651.         barRect.right =        r.right        - BarMargin;
  652.         barRect.bottom =    r.bottom    - BarMargin;
  653.         barRect.top =    barRect.bottom    - BarHeight;
  654.         
  655.         ButtonHndl = GetNewControl( kCancelButton, myWindow);
  656.         
  657.         barRect.right  -= ( BarMargin + (*ButtonHndl)->contrlRect.right);
  658.         OffsetRect(
  659.             &((*ButtonHndl)->contrlRect),
  660.             barRect.right + BarMargin,
  661.                  barRect.top -
  662.             ((*ButtonHndl)->contrlRect.bottom - (*ButtonHndl)->contrlRect.top - BarHeight)/2
  663.              );
  664.     
  665.         ShowControl(ButtonHndl);
  666.      
  667.         greyRect.left =        barRect.left    + 1;
  668.         greyRect.right =    greyRect.left;
  669.         greyRect.bottom =    barRect.bottom    - 1;
  670.         greyRect.top =        barRect.top        + 1;
  671.         
  672.         ShowWindow(myWindow);
  673.         DrawMovable(myWindow);
  674.     
  675.         SetPort(myWindow);
  676.     }
  677. }
  678.  
  679. void SetMMString( const char *fmt, ... )
  680. {
  681.     va_list            vl;
  682.     char            StrTmp[256];
  683.     
  684.     va_start(vl,fmt);
  685.         vsprintf(StrTmp, fmt, vl);
  686.     va_end(vl);
  687.  
  688.     CStrToStr255( SPDPstr, StrTmp );
  689.     
  690.     gDirtyStr = TRUE;
  691. }
  692.  
  693. static short FixMMString( void )
  694. {
  695.     int        newWid, newLen, wid;
  696.     
  697.     wid = (r.right - r.left) - 2 * BarMargin;
  698.     newWid = StringWidth(SPDPstr);
  699.     if (newWid > wid )
  700.     {
  701.         newLen = (int) SPDPstr[0];
  702.         wid = wid - CharWidth('ノ');
  703.         do
  704.         {
  705.             newWid = newWid - CharWidth(SPDPstr[newLen]);
  706.             newLen--;
  707.         }while((newWid > wid) && (SPDPstr[0] != 0x00));
  708.  
  709.         newLen ++;
  710.         SPDPstr[newLen] = 'ノ';
  711.         SPDPstr[0] = (char)newLen;
  712.     }
  713.     
  714.     return (StringWidth(SPDPstr));
  715. }    
  716.  
  717. static void DrawMsg(void)
  718. {
  719.     FontInfo    fInfo;
  720.     
  721.     TextFont( systemFont );
  722.     TextSize( 12 );
  723.     GetFontInfo( &fInfo );
  724.  
  725.     MsgRect.top = r.top + BarMargin - fInfo.ascent;
  726.     MsgRect.left = r.left + BarMargin;
  727.     
  728.     MsgRect.bottom = r.top + BarMargin + fInfo.descent;
  729. //    MsgRect.right = MsgRect.left + FixMMString();
  730.  
  731.     FixMMString();
  732.     MsgRect.right = r.right - BarMargin;
  733.     
  734.     EraseRect(&MsgRect) ;
  735.     
  736.     MoveTo( BarMargin , BarMargin);        /* h, v */
  737.     DrawString(SPDPstr);
  738.     
  739.     gDirtyStr = FALSE;
  740. }
  741.  
  742.  
  743. void ReleaseMovableModal(void)
  744. {
  745.     WindowPtr myWindow = FrontWindow();
  746.  
  747.     
  748.     
  749.      if(UseMModalProg)
  750.     {
  751.         if(ButtonHndl != nil)
  752.             DisposeControl(ButtonHndl);
  753.  
  754.         /* the front window really should be my modal window */
  755.         /* if it isn't, I'm bailing.*/
  756.  
  757.         gPrefs.SavedPoint.h = myWindow->portRect.left;
  758.         gPrefs.SavedPoint.v = myWindow->portRect.top;
  759.         LocalToGlobal(&gPrefs.SavedPoint);
  760.         if (((WindowPeek)myWindow)->windowKind == kMyModalKind)
  761.             CloseWindow(myWindow);
  762.     
  763.         UseMModalProg=false;
  764.     }
  765.     
  766.     
  767. }
  768.  
  769. static void DrawMovable(WindowPtr myWindow)
  770. {
  771.     WindowPtr            tempWP;
  772.  
  773.     BeginUpdate(myWindow);
  774.            GetPort(&tempWP);
  775.         SetPort(myWindow);
  776.  
  777.         DrawMsg();
  778.  
  779.         DrawBar(kIndicatorOutline | kIndicatorContent);
  780.         
  781.         DrawControls(myWindow);
  782.         
  783.         SetPort(tempWP);
  784.     EndUpdate(myWindow);
  785. }
  786.  
  787. static void DrawBar(short part)
  788. {
  789.     RGBColor    barColor        = {0x4444, 0x4444, 0x4444};
  790.     RGBColor    emptyBarColor    = {0xCCCC, 0xCCCC, 0xFFFF};
  791.     RGBColor    currentForeColor;
  792.     RGBColor    currentBackColor;
  793.  
  794.     if ((part & kIndicatorOutline) == kIndicatorOutline)
  795.     {
  796.         GetBackColor(¤tBackColor) ;
  797.         RGBBackColor(&emptyBarColor) ;
  798.         EraseRect(&barRect) ;
  799.         RGBBackColor(¤tBackColor) ;
  800.  
  801.         FrameRect(&barRect);
  802.         greyRect.left = barRect.left + 1;
  803.     }
  804.     
  805.     if ((part & kIndicatorContent) == kIndicatorContent)
  806.     {
  807.         GetForeColor(¤tForeColor);
  808.         RGBForeColor(&barColor);
  809.         PaintRect(&greyRect);
  810.         RGBForeColor(¤tForeColor);
  811.     }
  812. }
  813.  
  814. /************************************************************************************/
  815. HFileInfo    gpb;
  816.  
  817. static int DoOpen( FSSpec *fs )
  818. {
  819.     int                exitcode = 0;
  820.     HFileInfo        pb;
  821.  
  822.     pb.ioNamePtr    = fs->name;
  823.     pb.ioVRefNum    = fs->vRefNum;
  824.     pb.ioFDirIndex    = 0;                    /* query 1 item */
  825.     pb.ioDirID        = fs->parID;
  826.     
  827.     PBGetCatInfoSync( (CInfoPBPtr)&pb );
  828.     if (((pb.ioFlAttrib>>4) & 0x01) == 1)
  829.     {
  830.         /* Is a Dir */
  831.         if  ( gPrefs.Folder.RecurseMode == kFold_FNot )
  832.         {
  833.             exitcode = 3;
  834.         }
  835.         else
  836.         {
  837.             gpb.ioNamePtr = fs->name;
  838.             gpb.ioVRefNum = fs->vRefNum;
  839.     
  840.             exitcode = RecurseDir(pb.ioDirID);
  841.         }
  842.     }
  843.     else
  844.     {
  845.         /* Is a File */
  846.         gSufMap.Type = pb.ioFlFndrInfo.fdType;
  847.         
  848.         exitcode = gzip( fs );
  849.     }
  850.  
  851.     return exitcode;    
  852. }
  853.  
  854.  
  855. static int RecurseDir(long dirIDToSearch)
  856. {
  857.     short int    index=1;      /* for ioFDirIndex */
  858.     FSSpec        myFSSpec;
  859.     int            exitcode = 0;
  860.  
  861.     do
  862.     {
  863.         gpb.ioDirID        = dirIDToSearch;     
  864.         gpb.ioFDirIndex    = index;    /* set up the index */
  865.                                     /* we need to do this every time through,
  866.                                      * since GetCatInfo returns ioFlNum
  867.                                      * in this field
  868.                                      */
  869.         err= PBGetCatInfoSync((CInfoPBPtr)&gpb);
  870.  
  871.         if (err == noErr) 
  872.         {
  873.             /* check the file attributes for folderhood */
  874.             if (((gpb.ioFlAttrib>>4) & 0x01) == 1)
  875.             {
  876.                 if  ( gPrefs.Folder.RecurseMode == kFold_FAll )
  877.                 {
  878.                     exitcode = RecurseDir(gpb.ioDirID);
  879.                 }
  880.                 else
  881.                     exitcode = 0;
  882.                     
  883.                 err = 0;
  884.             }
  885.             else 
  886.             {
  887.                 FSMakeFSSpec(
  888.                         gpb.ioVRefNum,
  889.                         dirIDToSearch,
  890.                         gpb.ioNamePtr,
  891.                         &myFSSpec
  892.                         );
  893.                         
  894.                 exitcode =
  895.                     (0!=new_work( gApp.KeysMode, gApp.Op, gApp.Prompt, &myFSSpec ));
  896.             }
  897.              
  898.         index += 1;    /* increment the index for GetCatInfo */
  899.         }
  900.     } while ((err == noErr)&&( exitcode == 0));
  901.     
  902.     if ( err != fnfErr ) exitcode = 1;
  903.     return exitcode;
  904. }
  905.  
  906. /************************************************************************************/
  907.  
  908. static void BeginOfTask( void )
  909. {
  910.     gTask =  TRUE;
  911.     DisableItem(GetMenuHandle(kFileMenu), kfmOpen);
  912.     DisableItem(GetMenuHandle(kFileMenu), kfmCompress);
  913.     DisableItem(GetMenuHandle(kFileMenu), kfmExpand);
  914.     DisableItem(GetMenuHandle(kEditMenu), kemPrefs);
  915. }
  916.  
  917.  
  918. static Boolean EndOfTask( int errorcode )
  919. {
  920.     if ( gApp.Working )
  921.     {
  922.         if ( empty_work )
  923.         {
  924.             if ( 0 ==  errorcode )
  925.             {
  926.                 if ( gPrefs.Misc.BeepWhenDone )
  927.                     MyBeep(kBeepsnd_ID);
  928.             }
  929.             ReleaseMovableModal();
  930.             gApp.Working = FALSE;
  931.             SetCursor(&qd.arrow);                    
  932.         }
  933.         if ( SPDNow != nil) *SPDNow = 0;
  934.         SPDEnd=INT_MAX;
  935.     }
  936.     if ( empty_work )
  937.     {
  938.         gTask =  FALSE;
  939.         EnableItem(GetMenuHandle(kFileMenu), kfmOpen);
  940.         EnableItem(GetMenuHandle(kFileMenu), kfmCompress);
  941.         EnableItem(GetMenuHandle(kFileMenu), kfmExpand);
  942.         EnableItem(GetMenuHandle(kEditMenu), kemPrefs);
  943.     }
  944.     return (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone )) && empty_work ;
  945. }
  946.  
  947.